package com.zeus.core.sender.dingtalk;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.zeus.common.log.ZeusLoggerConfig;
import com.zeus.core.sender.ZeusDingTalkSender;
import com.taobao.api.internal.util.TaobaoLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * 钉钉机器人
 *
 * @author wangfeixiong126@gmail.com  2021/6/17 11:29
 */
public class DingTalkRoBot {
    private final static Logger logger = LoggerFactory.getLogger(DingTalkRoBot.class);

    /**
     * 钉钉机器人API地址
     */
    private static final String API_URL = "https://oapi.dingtalk.com/robot/send?access_token=";

    /**
     * webHook
     */
    private final String webHook;

    /**
     * secret
     */
    private final String secret;

    /**
     * 构造
     * 
     * @param accessToken   凭证
     * @param secret        秘钥
     * @author wangfeixiong126@gmail.com  2021/6/21 23:18
     */
    public DingTalkRoBot(String accessToken, String secret) {
        this.webHook = API_URL + accessToken;
        this.secret = secret;
    }

    /**
     * 发送Markdown消息
     * 
     * @param message 消息
     * @return  是否发送成功
     * @author wangfeixiong126@gmail.com  2021/6/21 23:09
     */
    public boolean sendMessage(ZeusDingTalkSender.MarkdownMessage message) {
        return send(message.toRequest());
    }

    /**
     * 发送钉钉消息
     * 
     * @param request 请求参数
     * @return  是否发送成功
     * @author wangfeixiong126@gmail.com  2021/6/21 23:09
     */
    private boolean send(OapiRobotSendRequest request) {
        try {
            // 关闭钉钉日志
            TaobaoLogger.setNeedEnableLogger(false);

            // 初始化客户端
            String apiUrl = getDingTalkApiUrl();
            DingTalkClient client = new DefaultDingTalkClient(apiUrl);
            OapiRobotSendResponse execute = client.execute(request);
            if (execute.isSuccess()) {
                return true;
            }
            if (logger.isWarnEnabled() && ZeusLoggerConfig.needEnableLogger()) {
                logger.warn("### Zeus报警服务, 钉钉机器人发送消息失败 >> errCode = {}, errMsg = {}", execute.getErrcode(),
                    execute.getErrmsg());
            }
        } catch (Exception e) {
            if (logger.isWarnEnabled() && ZeusLoggerConfig.needEnableLogger()) {
                logger.warn("### Zeus报警服务, 钉钉机器人发送消息出现了异常 >> errMsg = {}", e.getMessage());
            }
        }
        return false;
    }

    /**
     * 获取钉钉机器人api地址
     * 
     * @return 钉钉机器人api地址
     * @author wangfeixiong126@gmail.com  2021/6/21 23:07
     */
    private String getDingTalkApiUrl() throws InvalidKeyException, NoSuchAlgorithmException {
        if (secret != null && !secret.isEmpty()) {
            long timestamp = System.currentTimeMillis();
            return webHook + "&timestamp=" + timestamp + "&sign=" + sign(secret, timestamp);
        }
        return webHook;
    }

    /**
     * 签名
     * 
     * @param secret    秘钥
     * @param timestamp 时间戳
     * @return 签名
     * @author wangfeixiong126@gmail.com  2021/6/21 23:06
     */
    private static String sign(String secret, long timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(signData);
    }
}
